//
//  FZKaiShuDrawView.m
//  MrWrite
//
//  Created by Founder MAC on 14-12-17.
//  Copyright (c) 2014年 Founder. All rights reserved.
//

#import "FZKaiShuDrawView.h"


@implementation MyPoint

@synthesize my_nextPoint;
@synthesize my_prePoint;
@synthesize my_nextTime;
@synthesize my_preTime;
@synthesize my_nextWidth;
@synthesize my_preWidth;

@end

@interface FZKaiShuDrawView()
{
    CGFloat _deviceScale;
    GLint _backingWidth;
    GLint _backingHeight;
    CAEAGLLayer *_eaglLayer;
    EAGLContext *_context;
    GLuint _viewRenderbuffer;
    GLuint _viewFramebuffer;
    GLuint _brushTexture;
    
    MyPoint *_myPoint;
    
    CGPoint	_previousLocation;
    UInt64 _preNanoTime;
    CGFloat _preBrushWidth;
    
    // 撤销功能
    BOOL _isDrawMoved;
    NSMutableArray *_pointArray;
    NSMutableArray *_lineUndoArray;
    NSMutableArray *_pointListArray;
    
    // 压力感应
    BOOL _isSupportPressure;
    CGFloat _prePress;
    CGFloat _curPress;
    
    // 控制从第几个点开始绘制
    NSInteger _controlCount;
}

@property (nonatomic, retain) UIColor *chooseBrushColor;
@property (nonatomic, assign) CGFloat chooseBrushWidth;
@property (nonatomic, assign) WritingMode chooseBrushMode;

@end

#define OFFSET 0.0f

@implementation FZKaiShuDrawView

- (void)dealloc
{
    [_chooseBrushColor release], _chooseBrushColor = nil;
    [_lineUndoArray release], _lineUndoArray = nil;
    [_pointArray release], _pointArray = nil;
    [_pointListArray release], _pointListArray = nil;
    [_myPoint release], _myPoint = nil;
    
    [super dealloc];
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        _deviceScale = [UIScreen mainScreen].scale;
        _chooseBrushWidth = 20.0f;
        _isDrawMoved = NO;
        _isSupportPressure = NO;
        
        _pointArray = [[NSMutableArray alloc] init];
        _lineUndoArray = [[NSMutableArray alloc] init];
        _pointListArray = [[NSMutableArray alloc] init];
        
        _myPoint = [[MyPoint alloc] init];
        
        //配置OpenGL
        [self setupGLView];
        //绑定绘制上下文
        [EAGLContext setCurrentContext:_context];
        //销毁frmaebuffer
        [self destroyFramebuffer];
        //创建framebuffer
        [self createFramebuffer];
        //清空framebuffer内容
        [self clearFramebuffer];
    }
    return self;
}

#pragma mark - Override Method
+ (Class)layerClass
{
    return [CAEAGLLayer class];
}

- (void)layoutSubviews{
    
}

#pragma mark - Public Method
#pragma mark - 设置画笔宽度
- (void)p_setBrushWidth:(CGFloat)brushWidth
{
    self.chooseBrushWidth = 0.5f * (brushWidth * (1 + (self.frame.size.width - 250.0f) / 100.0f));
}

#pragma mark - 设置画笔颜色
- (void)p_setBrushColor:(UIColor*)color           //设置画笔颜色
{
    self.chooseBrushColor = color;
}

#pragma mark - 设置书写模式
- (void)p_setBrushMode:(WritingMode)writingMode
{
    if (writingMode == 1 || writingMode == 2) {
        _isSupportPressure = YES;
    } else {
        _isSupportPressure = NO;
    }
    
    self.chooseBrushMode = writingMode;
}

#pragma mark - 清空屏幕内容
- (void)p_clearTheScreen
{
    if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES) {
        [self clearFramebuffer];
        [_lineUndoArray removeAllObjects];
        
        //显示buffer
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer);
        [_context presentRenderbuffer:GL_RENDERBUFFER];
        
        [self.layer displayIfNeeded];
    }
    if(_scoreBlock != nil){
        self.scoreBlock(self.p_getDrawImage);
    }
}

#pragma mark - 撤销
- (void)p_undo
{
    [_lineUndoArray removeLastObject];
    
    [self clearFramebuffer];
    
    for (NSArray *pointArray in _lineUndoArray) {
        NSUInteger length = [pointArray count];
        GLfloat *vertexBuffer = (GLfloat *)malloc(length * sizeof(GLfloat));
        
        for (NSInteger i = 0; i < length; i++) {
            vertexBuffer[i] = [pointArray[i] floatValue];
        }
        
        glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
        glDrawArrays(GL_POINTS, 0, (GLsizei)(length / 2));
        
        free(vertexBuffer);
    }
    
    glBindRenderbuffer(GL_RENDERBUFFER, _viewRenderbuffer);
    [_context presentRenderbuffer:GL_RENDERBUFFER];
    if(_scoreBlock != nil){
        self.scoreBlock(self.p_getDrawImage);
    }
}

#pragma mark - 获取缓冲区图像
- (UIImage *)p_getDrawImage{
    CGFloat scale;
    if ([self respondsToSelector:@selector(contentScaleFactor)])
        scale = self.contentScaleFactor;
    else
        scale = 1.0f;
    
    NSInteger x = OFFSET * scale, y = OFFSET * scale,
    width = (self.frame.size.width - OFFSET * 2) * scale, height = (self.frame.size.height - OFFSET * 2) * scale;
    NSInteger dataLength = width * height * 4;
    GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte));
    
    //从framebuffer上读取像素数据
    glPixelStorei(GL_PACK_ALIGNMENT, 4);
    glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
    
    //根据像素数据创建CGImage，如果OpenGL ES的内容是不透明的，使用kCGImageAlphaNoneSkipLast忽略alpha通道，否则，使用kCGImageAlphaPremultipliedLast
    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL);
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast,
                                    ref, NULL, true, kCGRenderingIntentDefault);
    
    //创建图形上下文
    NSInteger widthInPoints, heightInPoints;
    if (NULL != UIGraphicsBeginImageContextWithOptions) {
        // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
        // Set the scale parameter to your OpenGL ES view's contentScaleFactor
        // so that you get a high-resolution snapshot when its value is greater than 1.0
        widthInPoints = width / scale;
        heightInPoints = height / scale;
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthInPoints, heightInPoints), NO, scale);
    }
    else {
        // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
        widthInPoints = width;
        heightInPoints = height;
        UIGraphicsBeginImageContext(CGSizeMake(widthInPoints, heightInPoints));
    }
    
    CGContextRef cgContext = UIGraphicsGetCurrentContext();
    
    //UIKit坐标系和OpenGl坐标系变换，翻转CGImage
    CGContextSetBlendMode(cgContext, kCGBlendModeCopy);
    CGContextDrawImage(cgContext, CGRectMake(0.0, 0.0, widthInPoints, heightInPoints), iref);
    
    //从当前上下文获取UIImage
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    //释放内存
    free(data);
    CFRelease(ref);
    CFRelease(colorspace);
    CGImageRelease(iref);
    
    return image;
}

#pragma mark - Private Method
#pragma mark - 配置OpenGL
- (void)setupGLView{
    if ([self respondsToSelector:@selector(contentScaleFactor)])
        self.contentScaleFactor = [UIScreen mainScreen].scale;
    CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
    eaglLayer.opaque = YES;
    
    //调用presentRenderbuffer后保留EAGLDrawable内容
    eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithBool:YES],
                                    kEAGLDrawablePropertyRetainedBacking,
                                    kEAGLColorFormatRGBA8,
                                    kEAGLDrawablePropertyColorFormat,
                                    nil];
    
    //初始化EAGLContext
    _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
    
    if (!_context || ![EAGLContext setCurrentContext:_context]) {
        //NSLog(@"error");
        return;
    }
    
    /* 方法: glMatrixMode
     作用: 指定当前矩阵
     参数: GL_MODELVIEW    对模型视景矩阵堆栈应用随后的矩阵操作
     GL_PROJECTION   对投影矩阵应用随后的矩阵操作
     GL_TEXTURE      对纹理矩阵堆栈应用随后的矩阵操作
     */
    glMatrixMode(GL_PROJECTION);
    
    //获取屏幕点包含像素数
    CGFloat scale;
    if ([self respondsToSelector:@selector(contentScaleFactor)])
        scale = self.contentScaleFactor;
    else
        scale = 1.0f;
    
    //Setup the view port in Pixels
    //设置修剪空间的范围
    glOrthof(0, (self.frame.size.width - OFFSET * 2) * scale, 0, (self.frame.size.height - OFFSET * 2) * scale, -1, 1);
    //定义一个像素矩形，最终将图像映射到这个矩形中,矩形大小为当前view的大小
    glViewport(OFFSET * scale, OFFSET * scale, (self.frame.size.width - OFFSET * 2)* scale, (self.frame.size.height - OFFSET * 2) * scale);
    glMatrixMode(GL_MODELVIEW);
    //If enabled, dither color components or indices before they are written to the color buffer
    glDisable(GL_DITHER);
    //启用二维纹理
    glEnable(GL_TEXTURE_2D);
    //顶点矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染
    glEnableClientState(GL_VERTEX_ARRAY);
    //启用颜色混合
    glEnable(GL_BLEND);
    //颜色混合设置，第一个参数GL_ONE表示完全使用源颜色参与混合运算，第二个参数GL_ONE_MINUS_SRC_ALPHA表示目标颜色用1.0减去目标颜色的alpha值来作为因子
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    
    glEnable(GL_POINT_SPRITE_OES);
    glEnable(GL_POINT_SMOOTH);
    glEnable(GL_LINE_SMOOTH);
    //设置贴图纹理
    glTexEnvf(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
    
    //设置每个点像素
    [self setPointSize:6.0f];
    
    //设置颜色
    const CGFloat *components = _chooseBrushColor ? CGColorGetComponents(_chooseBrushColor.CGColor) : CGColorGetComponents([UIColor whiteColor].CGColor);
    glColor4f(components[0], components[1], components[2], 1);
}

#pragma mark - 创建framebuffer
- (BOOL)createFramebuffer
{
    // Create default framebuffer object.
    glGenFramebuffersOES(1, &_viewFramebuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, _viewFramebuffer);
    
    // Create color render buffer and allocate backing store.
    glGenRenderbuffersOES(1, &_viewRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer);
    [_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer];
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &_backingWidth);
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &_backingHeight);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER_OES, _viewRenderbuffer);
    
    CGImageRef		brushImage;
    CGContextRef	brushContext;
    GLubyte			*brushData;
    size_t			width, height;
    // Create a texture from an image
    // First create a UIImage object from the data in a image file, and then extract the Core Graphics image
    NSString* imagePath = [[NSBundle mainBundle] pathForResource:@"write_doodle2.png" ofType:nil];
    brushImage = [UIImage imageWithContentsOfFile:imagePath].CGImage;
    
    // Get the width and height of the image
    width = CGImageGetWidth(brushImage);
    height = CGImageGetHeight(brushImage);
    
    // Texture dimensions must be a power of 2. If you write an application that allows users to supply an image,
    // you'll want to add code that checks the dimensions and takes appropriate action if they are not a power of 2.
    
    // Make sure the image exists
    if(brushImage) {
        // Allocate  memory needed for the bitmap context
        brushData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte));
        // Use  the bitmatp creation function provided by the Core Graphics framework.
        brushContext = CGBitmapContextCreate(brushData,
                                             width,
                                             height,
                                             8,
                                             width * 4,
                                             CGImageGetColorSpace(brushImage),
                                             kCGBitmapByteOrderDefault |kCGImageAlphaPremultipliedLast);
        // After you create the context, you can draw the  image to the context.
        CGContextDrawImage(brushContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), brushImage);
        // You don't need the context at this point, so you need to release it to avoid memory leaks.
        CGContextRelease(brushContext);
        // Use OpenGL ES to generate a name for the texture.
        glGenTextures(1, &_brushTexture);
        // Bind the texture name.
        glBindTexture(GL_TEXTURE_2D, _brushTexture);
        // Set the texture parameters to use a minifying filter and a linear filer (weighted average)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        // Specify a 2D texture image, providing the a pointer to the image data in memory
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, brushData);
        // Release  the image data; it's no longer needed
        free(brushData);
    }
    
    if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
    {
        return NO;
    }
    
    return YES;
}

#pragma mark - 销毁framebuffer
- (void)destroyFramebuffer
{
    if (_viewFramebuffer){
        glDeleteFramebuffersOES(1, &_viewFramebuffer);
        _viewFramebuffer = 0;
    }
    if (_viewRenderbuffer){
        glDeleteRenderbuffersOES(1, &_viewRenderbuffer);
        _viewRenderbuffer = 0;
    }
    if (_brushTexture)
    {
        glDeleteTextures(1, &_brushTexture);
        _brushTexture = 0;
    }
}

#pragma mark - 清空frameBuffer
- (void)clearFramebuffer
{
    [EAGLContext setCurrentContext:_context];
    
    //清空buffer
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, _viewFramebuffer);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    self.backgroundColor = [UIColor clearColor];
}

#pragma mark - 设置点像素宽度
- (void)setPointSize:(GLfloat)size;
{
    glPointSize(size);
}

#pragma mark - 获取点宽度
- (CGFloat)getBrushWidthFromPoint:(CGPoint)prePoint toPoint:(CGPoint)nextPoint withStartTime:(UInt64)preTime toEndTime:(UInt64)nextTime
{
    CGFloat brushWidth = 0.0f;
    brushWidth = sqrtf([self getDistanceFromPoint:prePoint toPoint:nextPoint] / ((nextTime - preTime) / 1000) * 100000);
    brushWidth = (CGFloat)_chooseBrushWidth * (CGFloat)pow(1.01, -(double)brushWidth * (double)brushWidth);
    
    if (_chooseBrushWidth > 15 * (1 + (self.frame.size.width - 250.0f) / 100.0f)) {
        brushWidth = (1.0f * brushWidth + 1.8f * _preBrushWidth) / 2.8f;
    } else{
        brushWidth = (1.0f * brushWidth + 1.5f * _preBrushWidth) / 2.5f;
    }
    
    if (HandwritingType_langhao == _handwritingType) {
        brushWidth = MAX(brushWidth, _chooseBrushWidth * 0.2f);
    } else if (HandwritingType_yanghao == _handwritingType) {
        brushWidth = MAX(brushWidth, _chooseBrushWidth * 0.5f);
    }
    
    brushWidth = MIN(brushWidth, _chooseBrushWidth);
    
    return brushWidth;
}

#pragma mark - 获取两点间距离
- (CGFloat)getDistanceFromPoint:(CGPoint)point1 toPoint:(CGPoint)point2
{
    CGFloat dis = (point1.x - point2.x) * (point1.x - point2.x) + (point1.y - point2.y) * (point1.y - point2.y);
    
    return sqrtf(dis);
}

#pragma mark - 笔形绘制
- (void)drawLineWithPoint:(MyPoint *)pointObj
{
    GLfloat*		vertexBuffer = NULL;
    NSUInteger	    vertexMax = 64;
    NSUInteger	    vertexCount = 0;
    
    [EAGLContext setCurrentContext:_context];
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, _viewFramebuffer);
    
    if(vertexBuffer == NULL)
        vertexBuffer = (GLfloat *)malloc(vertexMax * 2 * sizeof(GLfloat));
    
    CGPoint prePoint = pointObj.my_prePoint;
    CGPoint nextPoint = pointObj.my_nextPoint;
    CGFloat x = pointObj.my_nextPoint.x;
    CGFloat y = pointObj.my_nextPoint.y;
    CGFloat old_x = pointObj.my_prePoint.x;
    CGFloat old_y = pointObj.my_prePoint.y;
    CGFloat width = pointObj.my_nextWidth;
    CGFloat old_width = pointObj.my_preWidth;
    UInt64 t = pointObj.my_nextTime;
    UInt64 old_t = pointObj.my_preTime;
    
    CGFloat paint_X = 0.0f;
    CGFloat paint_Y = 0.0f;
    
    //TIANCHONG_A越小，段数越大，打得点数越多，笔形越密集
    NSInteger cnt = (NSInteger)((NSInteger)(fabs(x - old_x) + fabs(y - old_y))) / 2;
    if (cnt < 2) {
        cnt = 2;
    }
    
    // 设置一个防抖动的阈值
    CGFloat write_k = 1.0f;
    
    // 算法中这段代码在iOS中显示效果会出现异常，暂时注释掉
//    if (x - old_x > 3 && y - old_y > 3) {
//        write_k = _isSupportPressure ? 1.7f : 1.5f;
//    }
//    
//    if (x - old_x < -3 && y - old_y > -3) {
//        write_k = _isSupportPressure ? 0.6f : 0.75f;
//    }
    
    for (NSInteger i = 1; i <= cnt; i++){
        CGFloat x_write = old_x - (old_x - x)
        * ((CGFloat) i / (CGFloat) cnt);
        CGFloat y_write = old_y - (old_y - y)
        * ((CGFloat) i / (CGFloat) cnt);
        CGFloat width_write = old_width - (old_width - width)
        * ((CGFloat) i / (CGFloat) cnt);
        
        width_write *= write_k;
        
        double a = sqrt([self getDistanceFromPoint:prePoint toPoint:nextPoint]
                        / ((t - old_t) / 1000)
                        * 100000);
        NSInteger b = MAX(5, (NSInteger)((NSInteger)(30 + _chooseBrushWidth * _chooseBrushWidth) / ((NSInteger)a + 1)));

        if (HandwritingType_langhao == _handwritingType) {
            for (NSInteger j = 0; j < b; j++){
                if (((double)arc4random() / 0x100000000) > 0.7f) {
                    // 绘制笔形右部分
                    double r_x = ((double)arc4random() / 0x100000000) * 13;
                    double r_y = sqrt(13 * 13 - r_x
                                      * r_x)
                    * ((double)arc4random() / 0x100000000);
                    
                    if (((double)arc4random() / 0x100000000) > 0.5) {
                        r_y = -1.0f * r_y;
                    }
                    paint_X = (CGFloat) (x_write + width_write
                                         * r_x / 13);
                    paint_Y = (CGFloat) (y_write + r_y / 13
                                         * width_write);
                    
                    paint_X = paint_X;
                    paint_Y = self.frame.size.height * _deviceScale - paint_Y;
                } else {
                    // 绘制笔形左边笔锋部分
                    double r_x = ((double)arc4random() / 0x100000000) * -40;
                    double r_y = (r_x * r_x * 0.01852 - 13 + (0.005165
                                                              * r_x * r_x + 26 - r_x * r_x
                                                              * 0.01852)
                                  * ((double)arc4random() / 0x100000000)) * -1;
                    paint_X = (CGFloat) (x_write + r_x / 13
                                         * width_write);
                    paint_Y = (CGFloat) (y_write + r_y / 13
                                         * width_write);
                    
                    paint_X = paint_X;
                    paint_Y = self.frame.size.height * _deviceScale - paint_Y;
                }
                
                if (vertexCount == vertexMax) {
                    vertexMax = 2 * vertexMax;
                    vertexBuffer = (GLfloat *)realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat));
                }
                
                vertexBuffer[2 * vertexCount + 0] = paint_X;
                vertexBuffer[2 * vertexCount + 1] = paint_Y;
                vertexCount += 1;
                
                [_pointArray addObject:[NSNumber numberWithFloat:paint_X]];
                [_pointArray addObject:[NSNumber numberWithFloat:paint_Y]];
            }
        } else if (HandwritingType_yanghao == _handwritingType) {
            for (NSInteger j = 0; j < b; j++){
                if (((double)arc4random() / 0x100000000) > 0.7) {
                    // 绘制笔形右部分
                    double r_x = ((double)arc4random() / 0x100000000) * 13;
                    double r_y = sqrt(13 * 13 - r_x
                                      * r_x)
                    * ((double)arc4random() / 0x100000000);
                    
                    if (((double)arc4random() / 0x100000000) > 0.5) {
                        r_y = -1.0f * r_y;
                    }
                    paint_X = (CGFloat) (x_write + width_write
                                         * r_x / 13);
                    paint_Y = (CGFloat) (y_write + r_y / 13
                                         * width_write);
                    
                    paint_X = paint_X;
                    paint_Y = self.frame.size.height * _deviceScale - paint_Y;
                } else {
                    // 绘制笔形左边笔锋部分
                    double r_x = ((double)arc4random() / 0x100000000) * -40;
                    double r_y = (r_x * r_x * 0.01852 - 13 + (-0.005165
                                                              * r_x * r_x - 0.4508 * r_x + 26 - r_x * r_x
                                                              * 0.01852)
                                  * ((double)arc4random() / 0x100000000)) * -1;
                    paint_X = (CGFloat) (x_write + r_x / 13
                                         * width_write);
                    paint_Y = (CGFloat) (y_write + r_y / 13
                                         * width_write);
                    
                    paint_X = paint_X;
                    paint_Y = self.frame.size.height * _deviceScale - paint_Y;
                }
                
                if (vertexCount == vertexMax) {
                    vertexMax = 2 * vertexMax;
                    vertexBuffer = (GLfloat *)realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat));
                }
                
                vertexBuffer[2 * vertexCount + 0] = paint_X;
                vertexBuffer[2 * vertexCount + 1] = paint_Y;
                vertexCount += 1;
                
                [_pointArray addObject:[NSNumber numberWithFloat:paint_X]];
                [_pointArray addObject:[NSNumber numberWithFloat:paint_Y]];
            }
        }
    }
    //绘制点阵
    glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
    glDrawArrays(GL_POINTS, 0, (GLsizei)vertexCount);
    //显示图形
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer);
    [_context presentRenderbuffer:GL_RENDERBUFFER_OES];
    
    free(vertexBuffer);
}


- (void)drawWithPoint:(CGPoint)location state:(DrawingState)state  andTimestamp:(NSTimeInterval)timestamp{

    UInt64 nowNanoTime = timestamp * 1000 * 1000 * 1000; // 当前点触摸时间（纳秒级）
    if (DrawingState_Began == state) {
        [_pointArray removeAllObjects];
        
        _preBrushWidth = _chooseBrushWidth;
        
        [_pointListArray addObject:[NSNumber numberWithFloat:location.x]];
        [_pointListArray addObject:[NSNumber numberWithFloat:location.y]];
        
        const CGFloat *colorComponents = CGColorGetComponents(_chooseBrushColor.CGColor);
        glColor4f(colorComponents[0], colorComponents[1], colorComponents[2], 1);
    } else if (DrawingState_Changed == state) {
        // 过于相近的点不予显示，减少重复点数目
        if (fabsf(_previousLocation.x - location.x) + fabsf(_previousLocation.y - location.y) < 1.0f) {
            return;
        }
        
        [_pointListArray addObject:[NSNumber numberWithFloat:location.x]];
        [_pointListArray addObject:[NSNumber numberWithFloat:location.y]];
        
        CGFloat brushWidth = 0.0f;
        brushWidth = [self getBrushWidthFromPoint:_previousLocation toPoint:location withStartTime:_preNanoTime toEndTime:nowNanoTime];
        if (_isSupportPressure) {
            CGFloat d_press = _curPress - _prePress;
            if(d_press < 0) {
                d_press = d_press * 5.0f;
            } else {
                d_press = d_press * 2.0f;
            }
            
            if (_chooseBrushMode == WritingMode_Force) {
                brushWidth = _chooseBrushWidth * (d_press + 1.2f) * (d_press + 0.7f) * _curPress * 5.0f;
                brushWidth = (CGFloat)sqrt(brushWidth) * 5.0f;
            } else if (_chooseBrushMode == WritingMode_SpeedAndForce) {
                brushWidth = (CGFloat)sqrt((_chooseBrushWidth * (d_press + 1.2f) * (d_press + 0.7f) * _curPress * 5.0f) * brushWidth);
                brushWidth = (CGFloat)sqrt(brushWidth) * 5.0f;
            }
        }
        
        _myPoint.my_nextPoint = location;
        _myPoint.my_prePoint = _previousLocation;
        _myPoint.my_nextTime = nowNanoTime;
        _myPoint.my_preTime = _preNanoTime;
        _myPoint.my_nextWidth = brushWidth;
        _myPoint.my_preWidth = _preBrushWidth;
        
        [self drawLineWithPoint:_myPoint];
        _preBrushWidth = brushWidth;
        
        _isDrawMoved = YES;
    } else if (DrawingState_Ended == state || DrawingState_Cancelled == state) {
        if (_isDrawMoved) {
            _isDrawMoved = NO;
            
            NSArray *tempPointArray = [_pointArray copy];
            [_lineUndoArray addObject:tempPointArray];
            [tempPointArray release];
            
            if ([_pointListArray count] > 4 && location.x > 0) {
                CGFloat d_x = [[_pointListArray objectAtIndex:_pointListArray.count - 4] floatValue] - [[_pointListArray objectAtIndex:_pointListArray.count - 2] floatValue];
                CGFloat d_y = [[_pointListArray objectAtIndex:_pointListArray.count - 3] floatValue] - [[_pointListArray objectAtIndex:_pointListArray.count - 1] floatValue];
                CGFloat brushWidth = [self getBrushWidthFromPoint:_previousLocation toPoint:location withStartTime:_preNanoTime toEndTime:nowNanoTime];
                CGFloat d_width = brushWidth - _preBrushWidth;
                for (NSInteger i = 0; i < 6; i++) {
                    location.x = location.x - d_x * (CGFloat)pow(0.2, i);
                    location.y = location.y - d_y * (CGFloat)pow(0.2, i);
                    
                    [_pointListArray addObject:[NSNumber numberWithFloat:location.x]];
                    [_pointListArray addObject:[NSNumber numberWithFloat:location.y]];
                    CGFloat width = d_width * (CGFloat)pow(0.1, i);
                    _myPoint.my_nextPoint = location;
                    _myPoint.my_prePoint = _previousLocation;
                    _myPoint.my_nextTime = nowNanoTime;
                    _myPoint.my_preTime = _preNanoTime;
                    _myPoint.my_nextWidth = width;
                    _myPoint.my_preWidth = _preBrushWidth;
                    
                    _preBrushWidth = width;
                    _previousLocation = location;
                    _preNanoTime = nowNanoTime;
                    
                    [self drawLineWithPoint:_myPoint];
                }
            }
            [_pointListArray removeAllObjects];
        }
    }
    
    _previousLocation = location;
    _preNanoTime = nowNanoTime;
    _prePress = _curPress;
}

- (void)drawWithTouches:(NSSet *)touches withEvent:(UIEvent *)event withState:(DrawingState)state
{
    // 获取当前触摸点信息
    UITouch *touch = [[touches allObjects] objectAtIndex:0];
    CGPoint location = [touch locationInView:self];

    NSLog(@"nowNanoTime is:%f",touch.timestamp);
    
    // 坐标变换并转换成对应像素坐标
    location.x = location.x * _deviceScale;
    location.y = location.y * _deviceScale;
#ifdef __IPHONE_9_0
    if (_isSupportPressure && [[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0) {
        // 2015-11-9增加压感处理 by qk
        _curPress = touch.force / touch.maximumPossibleForce;
    }
#endif
    [self drawWithPoint:location state:state andTimestamp:touch.timestamp];
}

#pragma mark - touch事件处理
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    _controlCount++;
    [self setPointSize:6.0f];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    _controlCount++;
    if (_controlCount == 4) {
        // 开始
        [self drawWithTouches:touches withEvent:event withState:DrawingState_Began];
    } else if (_controlCount > 4) {
        // 移动
        [self drawWithTouches:touches withEvent:event withState:DrawingState_Changed];
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    _controlCount = 0;
    [self drawWithTouches:touches withEvent:event withState:DrawingState_Ended];
    
    if(_scoreBlock != nil){
        self.scoreBlock(self.p_getDrawImage);
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    _controlCount = 0;
    [self drawWithTouches:touches withEvent:event withState:DrawingState_Cancelled];
 
}

/*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 - (void)drawRect:(CGRect)rect
 {
 // Drawing code
 }
 */

@end
